package com.topc.oj.language.detail;

import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ObjectUtil;
import com.topc.oj.constant.OJConstant;
import com.topc.oj.enums.CodeStatusEnum;
import com.topc.oj.language.LanguageCodeDo;
import com.topc.oj.result.CodeCompileResult;
import com.topc.oj.result.CodeRunResult;
import com.topc.oj.runnable.code.CodeRunnable;


import java.util.concurrent.*;

public class PythonCodeDo implements LanguageCodeDo {

    private ProcessBuilder pb;

    private final static String CLASS_NAME = "main";

    private final String taskId = UUID.fastUUID().toString();

    @Override
    public CodeStatusEnum checkOutputStream(String s) {
        if (ObjectUtil.isEmpty(s)) return CodeStatusEnum.Finish;
        // 判断是否超时
        if (s.contains("Time Limit Exceeded")
                || s.contains("Execution Timed Out")
                || s.contains("Maximum Execution Time")
                || s.contains("Time Limit Reached")
                || s.contains("Program Timed Out")
        ) {
            return CodeStatusEnum.TLE;
        }

        // 判断是否内存超限
        if (s.contains("Out of Memory")
                || s.contains("Memory Limit Exceeded")
                || s.contains("Stack overflow")) {
            return CodeStatusEnum.MLE;
        }
        return CodeStatusEnum.Finish;
    }

    @Override
    public String taskId() {
        return taskId;
    }

    @Override
    public String fileSuffix() {
        return ".py";
    }

    @Override
    public String className() {
        return CLASS_NAME;
    }

    @Override
    public CodeCompileResult runCompile(String code) {
        return new CodeCompileResult().setCodeStatusEnum(CodeStatusEnum.Finish);
    }

    @Override
    public CodeRunResult run(String input, int timeLimit, int memoryLimit) {
        pb = new ProcessBuilder("python",OJConstant.SAVE_FILE_PATH +taskId+"\\"+CLASS_NAME+fileSuffix());
        ExecutorService executor = Executors.newSingleThreadExecutor();
        CodeRunnable codeRunnable = new CodeRunnable(pb, input, memoryLimit, timeLimit);
        Future<CodeRunResult> future = executor.submit(codeRunnable);
        CodeRunResult codeRunResult = new CodeRunResult();
        try {
            // codeRunResult = future.get(timeLimit, TimeUnit.MILLISECONDS);
            codeRunResult = future.get(2000, TimeUnit.MILLISECONDS); //奶奶滴，给我玩超时滴是吧，直接改吧！
            CodeStatusEnum codeStatusEnum = checkOutputStream(codeRunResult.getContentInfo());
        } catch (TimeoutException e) {
            codeRunResult.setCodeStatusEnum(CodeStatusEnum.TLE);
        } catch (InterruptedException | ExecutionException e) {
            codeRunResult.setCodeStatusEnum(CodeStatusEnum.UN_KNOW);
        }finally {
            executor.shutdownNow();
        }
        return codeRunResult;
    }
}
